#include "stdio.h"
#include "stddef.h"
#include "lw_timer.h"

/********************静态变量定义********************/
static lw_timer_hook_t lw_timer_hook;
static lw_timer_t* timer_list = NULL; /*静态链表头指针*/

/********************静态函数声明********************/
uint32_t time_diff(uint32_t start, uint32_t end);

/********************全局函数定义********************/

/**
 * @brief	设置时间戳获取函数
 * @param	time_stamp_get_func 用户提供的时间戳获取函数
 */
void lw_timer_set_stamp(uint32_t (*time_stamp_get_func)(void))
{
	lw_timer_hook.time_stamp_get = time_stamp_get_func;
}

/**
 * @brief	获取用户数据指针
 * @param	timer 软件定时器对象
 * @return	用户数据的指针
 */
void* get_timer_user_data(lw_timer_t *timer) 
{
    return timer->user_data;
}

/**
 * @brief	启动定时器
 * @param	timer 软件定时器对象
 * @param	callback 定时器超时回调函数
 * @param	user_data 用户数据的指针
 * @param	timeout 超时时间
 * @param	exec_count 定时器执行次数
 */
void lw_timer_start(lw_timer_t *timer, void (*callback)(lw_timer_t *), void *user_data, uint32_t timeout, int32_t exec_count) 
{
    timer->callback = callback;
    timer->user_data = user_data;
    timer->exec_count = exec_count;
    timer->start_time = lw_timer_hook.time_stamp_get();
    timer->timeout = timeout;
    timer->is_running = 1;

    /*将定时器对象加入链表*/
    timer->next = timer_list;
    timer_list = timer;
}

/**
 * @brief 停止定时器
 * @param timer 软件定时器对象
 */
void lw_timer_stop(lw_timer_t *timer) 
{
    lw_timer_t **current = &timer_list;

    while (*current != NULL) 
	{
        if (*current == timer) 
		{            
            *current = timer->next; /*移出链表*/
            timer->is_running = 0;
            break;
        }
        current = &((*current)->next);
    }
}

/**
 * @brief 定时器调度
 */
void lw_timer_scheduler(void) 
{
    uint32_t current_time = lw_timer_hook.time_stamp_get();
    lw_timer_t **current = &timer_list;

	/*遍历所有可执行的定时器*/
    while (*current != NULL) 
	{
        lw_timer_t *timer = *current;

        if (timer->is_running && time_diff(timer->start_time, current_time) >= timer->timeout) 
		{            
            timer->callback(timer); /*执行回调函数*/

			/*剩余执行次数更新*/
            if (timer->exec_count > 0) 
			{
                timer->exec_count--;
            }

			/*已完成所有轮次的执行*/
            if (timer->exec_count == 0) 
			{
                *current = timer->next; /*移出链表*/
                timer->is_running = 0;
            } 
			else 
			{               
                timer->start_time = current_time; /*定时器重装载*/
                current = &(timer->next);
            }
        } 
		else 
		{
            current = &(timer->next);
        }
    }
}

/********************静态函数定义********************/

/*计算时间差，考虑溢出情况*/
uint32_t time_diff(uint32_t start, uint32_t end) 
{
    if (end >= start) 
	{
        return end - start;
    } 
	else 
	{        
        return (UINT32_MAX - start) + end + 1; /*处理溢出情况*/
    }
}
